﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.IO;


namespace SimpleMultipleFileUploader
{
    public partial class FileUploadWindow : ChildWindow
    {
        #region Constants

        private readonly static int MAX_FILE_SLOTS = 6;

        private readonly static string DESTINATION_FOLDER = "upload_folder";

        #endregion

        #region Member Variables
        
        private FileInfo[] selectedFiles;

        #endregion

        #region Initializers

        public FileUploadWindow()
        {
            InitializeComponent();

            this.selectedFiles = new FileInfo[MAX_FILE_SLOTS];
            
            //Alows visual feedback when drag-dropping a file.
            this.AllowDrop = true;
            this.DragOver += (s, e) => VisualStateManager.GoToState(this, "Hover", true);
            this.DragLeave += (s, e) => VisualStateManager.GoToState(this, "Normal", true);
            this.Drop += new DragEventHandler(RootElement_Drop);


        }

        #endregion

        #region Drag and Drop
        
        private void RootElement_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileDrop"))
            {
                VisualStateManager.GoToState(this, "Normal", false);
   
                //An array of dropped-in files.
                FileInfo[] files = (FileInfo[])e.Data.GetData("FileDrop");
                
                //The index for the array that represents the dropped in files.
                int dropFileIndex = 0;

                //Try to register the dropped file with one of the file slots.
                for (int i = 0; i < MAX_FILE_SLOTS && dropFileIndex < files.Length; i++)
                {
                    //Check if the slot is empty.
                    if (selectedFiles[i] == null)
                    {
                        //Ignore duplicte files.
                        if (isFileSelected(files[dropFileIndex]))
                        {
                            MessageBox.Show(files[dropFileIndex].Name + " has already been selected. Ignoring this file.", "Duplicate File Selection", MessageBoxButton.OK);
                            dropFileIndex++;
                            continue;
                        }

                       //Store the selected files information.
                       selectedFiles[i] = files[dropFileIndex++];

                       //Find the text box representing the current file slot.
                       TextBox fileBox = ImportGrid.FindName("FileBox" + i) as TextBox;
                       
                       //Set the textbox's text value to equal the name of the file.
                       fileBox.Text = selectedFiles[i].Name ;
                       
                    }
                }

                //Check to see if all the dropped file could fit inside the available file upload space.
                if (dropFileIndex != files.Length)
                {
                    MessageBox.Show("Cannot register all files. Out of File Slots");
                }

               
            } 
        }
        

        /// <summary>
        /// Returns true if the file info has already been selected by the user.
        /// The method is used to disallow duplicate selection of files.
        /// </summary>
        /// <param name="fileInfo">The file info to check.</param>
        /// <returns>True if file info is already selected.</returns>
        private bool isFileSelected(FileInfo fileInfo)
        {
            //Iterate through each stored file.
            for (int i = 0; i < selectedFiles.Length; i++)

                //Check to to see if any one of the stored files equals fileInfo.
                if (selectedFiles[i] != null && selectedFiles[i].Name == fileInfo.Name)
                    return true;
            
            return false;
        }

        #endregion

        #region File Upload Process

        private void startFileUploadProcess()
        {
            //Create a file uploader.
            FileUploader fileUploader = new FileUploader();

            fileUploader.FileUploadStarted += new EventHandler(fileUploader_FileUploadStarted);
            fileUploader.AllFilesUploadCompleted += new EventHandler(fileUploader_AllFilesUploadCompleted);

            //Uploading the file.
            fileUploader.UploadFiles(selectedFiles, DESTINATION_FOLDER);
        }

        void fileUploader_AllFilesUploadCompleted(object sender, EventArgs e)
        {

            MessageBox.Show("All file uploades are complete!! :)");

            this.busyIndicator.IsBusy = false;
            this.busyIndicator.BusyContent = "";

            this.DialogResult = true;

        }

        void fileUploader_FileUploadStarted(object sender, EventArgs e)
        {
            if (e is FileUploadArgs)
            {
                this.busyIndicator.IsBusy = true;
                this.busyIndicator.BusyContent = "Uploading... " + ((FileUploadArgs)(e)).FileName;
            }


        }

        #endregion
        
        #region Button Event Handlers

        /// <summary>
        /// 
        /// 
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImportAllBttn_Click(object sender, RoutedEventArgs e)
        {

        
            //Disable the import button to not let the user click it twice and
            //cause uneccessary problems.
            this.ImportAllBttn.IsEnabled = false;

            //Counts the number of selected files.
            int fileCounter = 0;

            //Iterate through each file slot.
            for (int i = 0; i < selectedFiles.Length; i++)
            {
                //If the user hasn't input a filename, the file slot will be ignored.
                if (selectedFiles[i] == null) { continue; }

                //Increment the number of files processed.
                //Used to determine the total number of files that were processed.
                //Variable i may not be used for this purpose because, some 
                //file slots (represented by i) are null and are not files.
                fileCounter++;


            }

            //Start the file upload process only when at least one file
            //has been specified.
            if (fileCounter > 0)
            {
                this.busyIndicator.IsBusy = true;
                startFileUploadProcess();
            }
            
            //No files were selected.
            else
            {
                //Re-enable the import all button. 
                this.ImportAllBttn.IsEnabled = true;

                //Display a file-selection error.
                MessageBox.Show("No files were selected.");
            }
        }


        /// <summary>
        /// Opens the file browser, takes user input, and stores the file information
        /// in the correct array element of selectedFiles.
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// 
        private void BrowseButton_Click(object sender, RoutedEventArgs e)
        {

            //Get the button that triggered the button-click event.
            Button bttn = sender as Button;

            //The button's tag represents it's association with a file-name textbox.
            string bttnTag = (string)bttn.Tag;
            int fileIndex = Convert.ToInt32(bttnTag);

            //Set up and open a file browser dialog box.
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = false;

            //Sets the filters for file browsing.
            //ToDO: Set up correct filters. Probably something like *.XML.
            dlg.Filter = "All files | *.*";


            //Only continue if the user didn't click cancel.
            if ((bool)dlg.ShowDialog())
            {
                //Check for duplicate file selection.
                if (isFileSelected(dlg.File))
                {
                    MessageBox.Show("The file has already been selected.");
                    return;
                }

                TextBox fileBox = ImportGrid.FindName("FileBox" + bttnTag) as TextBox;

                //Set the textbox's text value to equal the name of the file.
                fileBox.Text = dlg.File.Name;

                //Store the selected files information.
                selectedFiles[fileIndex] = dlg.File;

            }

        }

        private void ClearAll_Click(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < selectedFiles.Length; i++)
            {

                //Set the text inside the file info textboxes to an empty string.
                (ImportGrid.FindName("FileBox" + i) as TextBox).Text = "";

                //Set the saved FileInfo files to null.
                selectedFiles[i] = null;

            }
        }

        private void CancelImportButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        #endregion
        
    }
}
